﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Collections;
using System.Configuration;
using System.Threading;
using System.Diagnostics;

namespace SQLServerSyncClient
{
    public partial class Form1 : Form
    {
        //用于存放收到的字符串数组
        Thread recvThread;
        DBUtility db;
        //用于接收数据的UDP对象
        UDP udp;
        public Form1()
        {
            InitializeComponent();
        }

        private void listView1_SizeChanged(object sender, EventArgs e)
        {
            this.columnHeader1.Width = listView1.Width / 6;
            this.columnHeader2.Width = listView1.Width / 6;
            this.columnHeader5.Width = listView1.Width / 2;
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            loadConfig();
            tabControl1.SelectTab(this.tabPage2);
            timer1.Interval = 1000 * 60 * 5;
        }

        private bool VerificationConfig()
        {
            bool ret = true;
            if (this.textBox1.Text.Trim() == "")
            {

                Log.Message(ref listView1, DateTime.Now, "SQLServer服务器IP必须填写");
                ret = false;
            };
            if (this.textBox2.Text.Trim() == "")
            {

                Log.Message(ref listView1, DateTime.Now, "数据库用户名必须填写");
                ret = false;
            };
            if (this.textBox4.Text.Trim() == "")
            {

                Log.Message(ref listView1, DateTime.Now, "数据库名称必须填写");
                ret = false;
            };

            Log.Message(ref listView1, DateTime.Now, "SQLServer客户端配置OK！");
            return ret;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            startListener();

            this.button2.Enabled = false;
            tabControl1.SelectTab(this.tabPage1);
            if (!VerificationConfig()) tabControl1.SelectTab(this.tabPage2);
            timer1.Start();

        }

        private void button3_Click(object sender, EventArgs e)
        {
            stopListener();
            this.button2.Enabled = true;

            tabControl1.SelectTab(this.tabPage1);

            timer1.Stop();
        }


        private string ReadConfig(string name)
        {
            Configuration config = System.Configuration.ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            KeyValueConfigurationElement key = config.AppSettings.Settings[name];
            if (key == null) return "";
            else
                return key.Value;
        }

        private void WriteConfig(string name, string value)
        {
            Configuration config = System.Configuration.ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            config.AppSettings.Settings.Remove(name);
            config.AppSettings.Settings.Add(name, value);
            //cfa.AppSettings.Settings[name].Value = value;
            config.Save();
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (recvThread != null)
                recvThread.Abort();

            if (db != null)
                db.Dispose();

            if (udp != null)
                udp.Close();
            saveConfig();
        }

        void loadConfig()
        {
            string tmp = ReadConfig("dbServer");
            if (tmp != "") textBox1.Text = tmp;

            tmp = ReadConfig("Uid");
            if (tmp != "") textBox2.Text = tmp;

            tmp = ReadConfig("Password");
            if (tmp != "") textBox3.Text = tmp;

            tmp = ReadConfig("dbName");
            if (tmp != "") textBox4.Text = tmp;

            tmp = ReadConfig("Port");
            if (tmp != "") numericUpDown2.Value = int.Parse(tmp);
        }

        void saveConfig()
        {
            WriteConfig("dbServer", textBox1.Text.Trim());
            WriteConfig("Uid", textBox2.Text.Trim());
            WriteConfig("Password", textBox3.Text.Trim());
            WriteConfig("dbName", textBox4.Text.Trim());
            WriteConfig("Port", numericUpDown2.Value.ToString());
        }

        private void button1_Click(object sender, EventArgs e)
        {
            saveConfig();
            Log.Message(ref listView1, DateTime.Now, "设置保存成功！");
        }


        private void startListener()
        {
            string server = this.textBox1.Text.Trim();
            string dbname = this.textBox4.Text.Trim();
            string uid = this.textBox2.Text.Trim();
            string password = this.textBox3.Text.Trim();

            db = new DBUtility(server, dbname, uid, password);
            udp = new UDP((int)this.numericUpDown2.Value);

            recvThread = new Thread(new ThreadStart(receiveListner));
            recvThread.Start();

            LogFileTools.WriteLog("接收服务启动");

            Log.Message(ref listView1, DateTime.Now, "启动接收服务！");
        }

        private void stopListener()
        {
            if (recvThread != null)
                recvThread.Abort();

            if (db != null)
                db.Dispose();

            if (udp != null)
            {
                udp.Close();
            }

            LogFileTools.WriteLog("接收服务停止");

            Log.Message(ref listView1, DateTime.Now, "停止接收服务！");
        }

        private void receiveListner()
        {
            while (true)
            {
                try
                {
                    DataTable dt = (DataTable)udp.ReceiveObject();

                    if (dt != null)//&& dt.Rows.Count == 10
                    {
                        string idsStr = "";

                        foreach (DataRow row in dt.Rows)
                        {
                            idsStr = idsStr + row["OriginalDataID"] + ",";
                        }
                        idsStr = idsStr.Remove(idsStr.Length - 1);

                        threadLogMsg(DateTime.Now, " 收到 " + dt.Rows.Count + " 条数据");

                        Debug.WriteLine(" 收到 " + dt.Rows.Count + " 条数据");
                        // 检查并排除重复数据
                        dt = checkExistsRows(dt);

                        Debug.WriteLine(" 检查后 " + dt.Rows.Count + " 条数据");
                        try
                        {
                            if (dt.Rows.Count > 0)
                            {
                                db.AddDataTableToDB(dt, "OriginalData");

                                threadLogMsg(DateTime.Now, " 入库 " + dt.Rows.Count + " 条数据");
                            }
                        }
                        catch (Exception ex)
                        {
                            LogFileTools.WriteLog("ID = [" + idsStr + "]入库时异常，异常信息：");
                            LogFileTools.WriteLog(ex.ToString());
                            throw ex;
                        }

                        continue;
                    }
                    else
                    {
                        LogFileTools.WriteLog("接收数据为空！");
                    }
                }
                catch (ThreadAbortException ){ }
                catch (Exception e)
                {
                    Debug.WriteLine(e.ToString());
                    threadLogMsg(DateTime.Now, e.Message);
                }
            }
        }

        private DataTable checkExistsRows(DataTable dt)
        {
            string idsStr = "";

            foreach(DataRow row in dt.Rows)
            {
                idsStr = idsStr + row["OriginalDataID"] + ",";
            }
            idsStr = idsStr.Remove(idsStr.Length - 1);

            string sql = "SELECT OriginalDataID FROM OriginalData WHERE OriginalDataID in( " + idsStr + ")";
            DataSet existsDs = db.ExecuteDS(sql);
            
            if(existsDs.Tables[0].Rows.Count <= 0)
            {
                return dt;
            }
            
            for(int i = 0; i < dt.Rows.Count; i++)
            {
                foreach(DataRow existsRow in existsDs.Tables[0].Rows)
                {
                    if(Convert.ToInt32(dt.Rows[i]["OriginalDataID"].ToString())== Convert.ToInt32(existsRow["OriginalDataID"].ToString()))
                    {
                        //LogFileTools.WriteLog("ID = [" + Convert.ToInt32(dt.Rows[i]["OriginalDataID"].ToString()) + "]与表相等，需要踢除");
                        dt.Rows.Remove(dt.Rows[i]);
                        i--;
                        //LogFileTools.WriteLog("ID = [" + Convert.ToInt32(dt.Rows[i]["OriginalDataID"].ToString()) + "]已踢除");
                        break;
                    }
                }
            }
            dt.AcceptChanges();

            return dt;
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            DialogResult result = MessageBox.Show("确定要关闭吗？", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
            if (result == DialogResult.OK)
            {
                Application.Exit();//关闭程序
            }
            else
            {
                e.Cancel = true;//保持状态，这句必须有，防止有时候点了 “取消” 还是照样关闭
                //this.Hide(); //隐藏窗体 
                this.ShowInTaskbar = true;//图标不显示在任务栏上 
            }

            saveConfig();
        }

        private void threadLogMsg(DateTime dt1, string Msg)
        {
            this.Invoke(new Action(() =>
            {
                Log.Message(ref listView1, dt1, Msg);
            }));
        }

        private void threadLogMsg(DateTime dt1, string Msg, string tbName)
        {
            this.Invoke(new Action(() =>
            {
                Log.Message(ref listView1, dt1, Msg, tbName);
            }));
        }

        private void button4_Click(object sender, EventArgs e)
        {
            System.Diagnostics.Process.Start("explorer.exe", ".\\FailedLogFiles\\");
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            Log.Message(ref listView1, DateTime.Now, "接收服务运行中........");
        }

        private void Form1_FormClosed_1(object sender, FormClosedEventArgs e)
        {
            if (recvThread != null)
                recvThread.Abort();

            if (db != null)
                db.Dispose();

            if (udp != null)
            {
                udp.Close();
                udp = null;
            }

            timer1.Stop();
        }
    }
}
